home *** CD-ROM | disk | FTP | other *** search
/ Creating Your Own America Online Web Pages / Creating Your Own America Online Web Pages.iso / TOOLS / TEX2RTF / SOURCES.ZIP / SRC / WXWIN / WB_LIST.CC < prev    next >
Encoding:
C/C++ Source or Header  |  1994-01-31  |  10.5 KB  |  513 lines

  1. /*
  2.  * File:     wx_list.cc
  3.  * Purpose:  List implementation
  4.  *
  5.  *                        wxWindows 1.50
  6.  * Copyright (c) 1993 Artificial Intelligence Applications Institute,
  7.  *                   The University of Edinburgh
  8.  *
  9.  *                     Author: Julian Smart
  10.  *                       Date: 7-9-93
  11.  *
  12.  * Permission to use, copy, modify, and distribute this software and its
  13.  * documentation for any purpose is hereby granted without fee, provided
  14.  * that the above copyright notice, author statement and this permission
  15.  * notice appear in all copies of this software and related documentation.
  16.  *
  17.  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, EXPRESS,
  18.  * IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF
  19.  * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
  20.  *
  21.  * IN NO EVENT SHALL THE ARTIFICIAL INTELLIGENCE APPLICATIONS INSTITUTE OR THE
  22.  * UNIVERSITY OF EDINBURGH BE LIABLE FOR ANY SPECIAL, INCIDENTAL, INDIRECT OR
  23.  * CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER RESULTING FROM
  24.  * LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF THE POSSIBILITY OF
  25.  * DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH
  26.  * THE USE OR PERFORMANCE OF THIS SOFTWARE.
  27.  */
  28.  
  29. /* Uncomment for Borland/UNIX combination
  30. #ifdef wx_msw
  31. #include "wx.h"
  32. #pragma hdrstop
  33. #else
  34.  
  35. #include "common.h"
  36. #include "wx_list.h"
  37. #include "wx_utils.h"
  38. #endif
  39. */
  40.  
  41. #include "wx.h"                         // MSC 7/UNIX
  42. #include <stdarg.h>
  43. #include <stdlib.h>
  44.  
  45. wxNode::wxNode(wxList *the_list, wxNode *last_one, wxNode *next_one,
  46.                wxObject *object)
  47. {
  48.   __type = wxTYPE_NODE;
  49.   data = object;
  50.   previous = last_one;
  51.   next = next_one;
  52.   list = the_list;
  53.   key.string = NULL;
  54.  
  55.   if (previous)
  56.     previous->next = this;
  57.  
  58.   if (next)
  59.     next->previous = this;
  60. }
  61.  
  62. // Keyed constructor
  63. wxNode::wxNode(wxList *the_list, wxNode *last_one, wxNode *next_one,
  64.                wxObject *object, long the_key)
  65. {
  66.   __type = wxTYPE_NODE;
  67.   data = object;
  68.   previous = last_one;
  69.   next = next_one;
  70.   list = the_list;
  71.   key.integer = the_key;
  72.  
  73.   if (previous)
  74.     previous->next = this;
  75.  
  76.   if (next)
  77.     next->previous = this;
  78. }
  79.  
  80. wxNode::wxNode(wxList *the_list, wxNode *last_one, wxNode *next_one,
  81.                wxObject *object, char *the_key)
  82. {
  83.   __type = wxTYPE_NODE;
  84.   data = object;
  85.   previous = last_one;
  86.   next = next_one;
  87.   list = the_list;
  88.   key.string = copystring(the_key);
  89.  
  90.   if (previous)
  91.     previous->next = this;
  92.  
  93.   if (next)
  94.     next->previous = this;
  95. }
  96.  
  97.  
  98. wxNode::~wxNode(void)
  99. {
  100.   if (list)
  101.     list->n --;
  102.  
  103.   if (list && list->destroy_data)
  104.     delete data;
  105.  
  106.   if (list && list->key_type == wxKEY_STRING && key.string)
  107.     delete[] key.string;
  108.  
  109.   // Make next node point back to the previous node from here
  110.   if (next)
  111.     next->previous = previous;
  112.   else if (list)
  113.     // If there's a new end of list (deleting the last one)
  114.     // make sure the list knows about it.
  115.     list->last_node = previous;
  116.  
  117.   // Make the previous node point to the next node from here
  118.   if (previous)
  119.     previous->next = next;
  120.  
  121.   // Or if no previous node (start of list), make sure list points at
  122.   // the next node which becomes the first!.
  123.   else if (list)
  124.     list->first_node = next;
  125. }
  126.  
  127. wxList::wxList(void)
  128. {
  129.   __type = wxTYPE_LIST;
  130.   first_node = NULL;
  131.   last_node = NULL;
  132.   n = 0;
  133.   destroy_data = 0;
  134.   key_type = wxKEY_NONE;
  135. }
  136.  
  137. wxList::wxList(int N, wxObject *Objects[])
  138. {
  139.   __type = wxTYPE_LIST;
  140.   wxNode *last = NULL;
  141.  
  142.   for (int i = 0; i < N; i ++)
  143.   {
  144.     wxNode *next = new wxNode(this, last, NULL, Objects[i]);
  145.     last = next;
  146.     if (i == 0) first_node = next;
  147.   }
  148.   last_node = last;
  149.   n = N;
  150.   key_type = wxKEY_NONE;
  151. }
  152.  
  153. wxList::wxList(unsigned int the_key_type)
  154. {
  155.   __type = wxTYPE_LIST;
  156.   n = 0;
  157.   destroy_data = 0;
  158.   first_node = NULL;
  159.   last_node = NULL;
  160.   key_type = the_key_type;
  161. }
  162.  
  163. // Variable argument list, terminated by a zero
  164. wxList::wxList(wxObject *first_one ...)
  165. {
  166. #ifndef __sgi
  167.   __type = wxTYPE_LIST;
  168.   va_list ap;
  169.  
  170.   va_start(ap, first_one);
  171.  
  172.   wxNode *last = new wxNode(this, NULL, NULL, first_one);
  173.   first_node = last;
  174.   n = 1;
  175.  
  176.   for (;;)
  177.   {
  178.     wxObject *object = va_arg(ap, wxObject *);
  179. //    if (object == NULL) // Doesn't work in Windows -- segment is non-zero for NULL!
  180.     if ((int)object == 0)
  181.       break;
  182.     else
  183.       { wxNode *node = new wxNode(this, last, NULL, object);
  184.         last = node;
  185.         n++;
  186.       }
  187.   }
  188.   last_node = last;
  189.   va_end(ap);
  190.  
  191.   destroy_data = 0;
  192.   key_type = wxKEY_NONE;
  193. #else
  194.   fprintf(stderr, "Error: cannot use variable-argument functions on SGI!\n");
  195. #endif
  196. }
  197.  
  198. wxList::~wxList(void)
  199. {
  200.   wxNode *each = first_node;
  201.   while (each)
  202.   {
  203.     wxNode *next = each->Next();
  204.     delete each;
  205.     each = next;
  206.   }
  207. }
  208.  
  209. wxNode *wxList::Nth(int i)
  210. {
  211.   int j = 0;
  212.   wxNode *current = First();
  213.   while (current && j < i)
  214.   {
  215.     current = current->Next();
  216.     j ++;
  217.   }
  218.   if (j == i)
  219.     return current;
  220.   else
  221.     return NULL;
  222. }
  223.  
  224. wxNode *wxList::Find(long key)
  225. {
  226.   wxNode *current = First();
  227.   wxNode *found = NULL;
  228.   while (current && !found)
  229.   {
  230.     if (current->key.integer == key)
  231.       found = current;
  232.     else current = current->Next();
  233.   }
  234.   return found;
  235. }
  236.  
  237. wxNode *wxList::Find(char *key)
  238. {
  239.   wxNode *current = First();
  240.   wxNode *found = NULL;
  241.   while (current && !found)
  242.   {
  243.     if (!current->key.string)
  244.     {
  245.       wxFatalError("wxList: string key not present, probably did not Append correctly!");
  246.       return NULL;
  247.     }
  248.     if (strcmp(current->key.string, key) == 0)
  249.       found = current;
  250.     else current = current->Next();
  251.   }
  252.   return found;
  253. }
  254.  
  255. wxNode *wxList::Member(wxObject *object)
  256. {
  257.   wxNode *current = First();
  258.   wxNode *found = NULL;
  259.   while (current && !found)
  260.   {
  261.     wxObject *each = current->Data();
  262.     if (each == object)
  263.       found = current;
  264.     else current = current->Next();
  265.   }
  266.   return found;
  267. }
  268.  
  269. Bool wxList::DeleteNode(wxNode *node)
  270. {
  271.   if (node)
  272.   {
  273.     delete node;
  274.     return TRUE;
  275.   }
  276.   else
  277.     return FALSE;
  278. }
  279.  
  280. Bool wxList::DeleteObject(wxObject *object)
  281. {
  282.   wxNode *current = first_node;
  283.   while (current)
  284.   {
  285.     if (current->Data() == object)
  286.       break;
  287.     else current = current->Next();
  288.   }
  289.   if (current)
  290.   {
  291.     delete current;
  292.     return TRUE;
  293.   }  else return FALSE;
  294. }
  295.  
  296.  
  297. // Insert new node at front of list
  298. wxNode *wxList::Insert(wxObject *object)
  299. {
  300.   wxNode *node = new wxNode(this, NULL, First(), object);
  301.   first_node = node;
  302.  
  303.   if (!(node->Next()))
  304.     last_node = node;
  305.  
  306.   n ++;
  307.   return node;
  308. }
  309.  
  310.  
  311. // Insert new node before given node.
  312. wxNode *wxList::Insert(wxNode *position, wxObject *object)
  313. {
  314.   wxNode *prev = NULL;
  315.   if (position)
  316.     prev = position->Previous();
  317.  
  318.   wxNode *node = new wxNode(this, prev, position, object);
  319.   if (!first_node)
  320.   {
  321.     first_node = node;
  322.     last_node = node;
  323.   }
  324.   if (!prev)
  325.     first_node = node;
  326.  
  327.   n ++;
  328.   return node;
  329. }
  330.  
  331. // Keyed append
  332. wxNode *wxList::Append(long key, wxObject *object)
  333. {
  334.   wxNode *node = new wxNode(this, last_node, NULL, object, key);
  335.   if (!first_node)
  336.     first_node = node;
  337.   last_node = node;
  338.   n ++;
  339.   return node;
  340. }
  341.  
  342. wxNode *wxList::Append(char *key, wxObject *object)
  343. {
  344.   wxNode *node = new wxNode(this, last_node, NULL, object, key);
  345.   if (!first_node)
  346.     first_node = node;
  347.   last_node = node;
  348.   n ++;
  349.   return node;
  350. }
  351.  
  352. void wxList::Clear(void)
  353. {
  354.   wxNode *current = first_node;
  355.   while (current)
  356.   {
  357.     wxNode *next = current->Next();
  358.     delete current;
  359.     current = next;
  360.   }
  361.   first_node = NULL;
  362.   last_node = NULL;
  363.   n = 0;
  364. }
  365.  
  366. /*
  367.  * String list
  368.  *
  369.  */
  370.  
  371. wxStringList::wxStringList(void):wxList()
  372. {
  373.   __type = wxTYPE_STRING_LIST;
  374. }
  375.  
  376. // Variable argument list, terminated by a zero
  377. // Makes new storage for the strings
  378. wxStringList::wxStringList(char *first ...)
  379. {
  380. #ifndef __sgi
  381.   __type = wxTYPE_STRING_LIST;
  382.   n = 0;
  383.   destroy_data = 0;
  384.   key_type = wxKEY_NONE;
  385.   first_node = NULL;
  386.   last_node = NULL;
  387.  
  388.   if (!first)
  389.     return;
  390.  
  391.   va_list ap;
  392.  
  393.   va_start(ap, first);
  394.  
  395.   wxNode *last = new wxNode(this, NULL, NULL, (wxObject *)copystring(first));
  396.   first_node = last;
  397.   n = 1;
  398.  
  399.   for (;;)
  400.   {
  401.     char *s = va_arg(ap, char *);
  402. //    if (s == NULL)
  403.     if ((int)s == 0)
  404.       break;
  405.     else
  406.       { wxNode *node = new wxNode(this, last, NULL, (wxObject *)copystring(s));
  407.         last = node;
  408.         n++;
  409.       }
  410.   }
  411.   last_node = last;
  412.   va_end(ap);
  413. #else
  414.   fprintf(stderr, "Error: cannot use variable-argument functions on SGI!\n");
  415. #endif
  416. }
  417.  
  418. wxStringList::~wxStringList(void)
  419. {
  420.   wxNode *each = first_node;
  421.   while (each)
  422.   {
  423.     char *s = (char *)each->Data();
  424.     delete[] s;
  425.     wxNode *next = each->Next();
  426.     delete each;
  427.     each = next;
  428.   }
  429. }
  430.  
  431. wxNode *wxStringList::Add(char *s)
  432. {
  433.   return Append((wxObject *)(copystring(s)));
  434. }
  435.  
  436. void wxStringList::Delete(char *s)
  437. {
  438.   wxNode *node = First();
  439.   Bool found = FALSE;
  440.   while (node && !found)
  441.   {
  442.     char *string = (char *)node->Data();
  443.     if (strcmp(string, s) == 0)
  444.     {
  445.       found = TRUE;
  446.       delete[] string;
  447.       delete node;
  448.     }
  449.     else node = node->Next();
  450.   }
  451. }
  452.  
  453. // Only makes new strings if arg is TRUE
  454. char **wxStringList::ListToArray(Bool new_copies)
  455. {
  456.   char **string_array = new char *[Number()];
  457.   wxNode *node = First();
  458.   for (int i = 0; i < n; i++)
  459.   {
  460.     char *s = (char *)node->Data();
  461.     if (new_copies)
  462.       string_array[i] = copystring(s);
  463.     else
  464.       string_array[i] = s;
  465.     node = node->Next();
  466.   }
  467.   return string_array;
  468. }
  469.  
  470. int wx_comparestrings(const void *arg1, const void *arg2)
  471. {
  472.   char **s1 = (char **)arg1;
  473.   char **s2 = (char **)arg2;
  474.  
  475.   return strcmp(*s1, *s2);
  476. }
  477.  
  478. // Sort a list of strings - deallocates old nodes, allocates new
  479. void wxStringList::Sort(void)
  480. {
  481.   int N = n;
  482.   char **array = new char *[N];
  483.   int i = 0;
  484.   wxNode *node = First();
  485.   while (node)
  486.   {
  487.     array[i] = (char *)node->Data();
  488.     i ++;
  489.     node = node->Next();
  490.   }
  491.   qsort(array, N, sizeof(char *), wx_comparestrings);
  492.   Clear();
  493.  
  494.   for (i = 0; i < N; i++)
  495.     Append((wxObject *)(array[i]));
  496.  
  497.   delete[] array;
  498. }
  499.  
  500. // Checks whether s is a member of the list
  501. Bool wxStringList::Member(char *s)
  502. {
  503.   wxNode *node = First();
  504.   while (node)
  505.   {
  506.     char *s1 = (char *)node->Data();
  507.     if (strcmp(s, s1) == 0)
  508.       return TRUE;
  509.     else node = node->Next();
  510.   }
  511.   return FALSE;
  512. }
  513.